﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;

namespace Galaktika.BI.Silverlight.ClientApp.Services
{
    using Galaktika.BI.Runtime;
    using Galaktika.BI.Runtime.Services;
    using Galaktika.BI.Silverlight.Services;

    public class ScriptEngineImpl : IScriptEngine
    {
        public ScriptEngineImpl()
        {
        }

        private static FieldInfo m_Caller;
        internal FieldInfo Caller
        {
            get
            {
                if (m_Caller == null)
                {
                    Type type = ClientResources.ClientAssembly.GetType(
                        string.Format("{0}.{1}", Consts.GLOBAL_NAMESPACE, Consts.CURRENT_CLASS_NAME), true);
                    m_Caller = type.GetField(Consts.CALLER_FIELD_NAME, BindingFlags.Public | BindingFlags.Static);
                }

                return m_Caller;
            }
        }

        public void Execute(string scriptId, object target, IDictionary<string, string> param)
        {
            this.Caller.SetValue(null, target as IBindableObject);
            if (!(param is SafeDictionary<string, string>))
            {
                SafeDictionary<string, string> newParam = new SafeDictionary<string, string>();
                foreach (KeyValuePair<string, string> kv in param)
                {
                    newParam.Add(kv);
                }
                param = newParam;
            }
            Type scriptType = ClientResources.ClientAssembly.GetType(scriptId);
            if (scriptType != null)
            {
                MethodInfo invoker = scriptType.GetMethod(
                    Consts.ACTION_INVOKE_METHOD_NAME,
                    BindingFlags.Public | BindingFlags.Static);
                if (invoker != null)
                {
                    if (param == null)
                    {
                        param = new SafeDictionary<string, string>();
                    }
                    invoker.Invoke(null, new object[] { param });
                }
            }
        }

        #region IScriptEngine Members

        FuncInvokeCheckResult IScriptEngine.CheckFuncInvoke(string str)
        {
            return ScriptEngine.CheckFuncInvoke(str);
        }

        string IScriptEngine.InvokeFunction(IBindingContext context, FuncInvokeCheckResult check)
        {
            return ScriptEngine.InvokeFunction(context, check, ClientResources.ClientAssembly);
        }

        #endregion
    }
}
